package com.zhangh.summer.admin.support.session;

import com.zhangh.summer.admin.support.ds.common.MixedDS;
import com.zhangh.summer.admin.support.log.LogRecorder;
import com.zhangh.summer.admin.support.utils.UUIDGenerator;
import com.zhangh.summer.admin.support.utils.json.JsonEncoder;
import com.zhangh.summer.admin.support.spring.util.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.Optional;

@Slf4j
public class SessionInterceptor implements HandlerInterceptor {
    private static final String TRACE_ID_KEY="traceID";
    private static final String TOKEN_KEY="token";
    private static final String USER_KEY="user";
    private static final String USER_ID_KEY="userID";
    private MixedDS mixedDS;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        //trace
        Optional.ofNullable(request.getHeader(TRACE_ID_KEY)).ifPresent(traceID->{
            if (StringUtils.isBlank(traceID)){
                traceID= UUIDGenerator.random32UUID();
                log.warn("source traceID is null create new traceID:{}",traceID);
            }
            MDC.put(TRACE_ID_KEY,traceID);
            SysSession.setTraceID(traceID);
        });

        //token
        String token=request.getHeader(TOKEN_KEY);
        //String user= URLDecoder.decode(request.getHeader(USER_KEY),"UTF-8");//gateway 已经赋值了
        if (StringUtils.isNotBlank(token)){
            String user;
            String userData=request.getHeader(USER_KEY);
            if (StringUtils.isBlank(userData)){
                user=getUserFromRedis(token);
                log.info("token {} ,user {}",token,user );
                //log.error("userData is null");
                //throw BizException.exception("userData is null");
            }else{
                user= URLDecoder.decode(userData,"UTF-8");
            }
            SessionUser sessionUser= JsonEncoder.DEFAULT.decode(user,SessionUser.class);
            if (null!=sessionUser){
                sessionUser.setToken(token);
                MDC.put(USER_ID_KEY,String.valueOf(sessionUser.getUserID()));
                SysSession.setUser(sessionUser);
            }else{
                LogRecorder.instance().logger(log).error("获取用户session失败 token {} ",token);
                return false;
            }
        }else{
            LogRecorder.instance().logger(log).error("获取用户session失败 token {} ",token);
            return false;
        }
        return true;
    }

    private String getUserFromRedis(String token){
        if (null==mixedDS){
            mixedDS= SpringBeanUtil.getBeanByType(MixedDS.class);
        }
        String user=mixedDS.redis().get(token);
        return user;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        if (StringUtils.isNotBlank(SysSession.getTraceID())) {
            httpServletResponse.setHeader(TRACE_ID_KEY, SysSession.getTraceID());
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}
